package com.decheng.mq.config;

import com.decheng.mq.receiver.FanoutReceiver;
import com.decheng.mq.sender.FanoutSender;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 孔德成
 * @slogan 致敬大师，致敬未来的你
 * @date 2021/9/16 3:10 下午
 * @desc 发布/订阅模式是指同时向多个消费者发送消息的模式（类似广播的形式），
 * 它包含一个生产者、两个消费者、两个队列和一个交换机。两个消费者同时绑定到不同的队列上去，
 * 两个队列绑定到交换机上去，生产者通过发送消息到交换机，所有消费者接收并消费消息。
 * <p>
 * 创建一个名为 exchange.fanout 的交换机、一个生产者、两个消费者和两个匿名队列，
 * 将两个匿名队列都绑定到交换机；
 * <p>
 * 运行后结果：生产者往队列中发送包含不同数量.号的消息，instance 1和instance 2同时获取并消费了消息。
 */
@Configuration
public class FanoutRabbitConfig {
    /**
     * @return 创建一个名为 exchange.fanout 的交换机
     */
    @Bean
    public FanoutExchange fanout() {
        return new FanoutExchange("exchange.fanout");
    }

    /**
     * @return 创建一个匿名队列
     */
    @Bean
    public Queue fanoutQueue1() {
        return new AnonymousQueue();
    }

    @Bean
    public Queue fanoutQueue2() {
        return new AnonymousQueue();
    }

    /**
     * 将 fanoutQueue1 绑定到 exchange.fanout 交换机
     *
     * @param fanout       exchange.fanout 交换机
     * @param fanoutQueue1 fanoutQueue1
     * @return
     */
    @Bean
    public Binding fanoutBinding1(FanoutExchange fanout, Queue fanoutQueue1) {
        return BindingBuilder.bind(fanoutQueue1).to(fanout);
    }

    /**
     * 将 fanoutQueue2 绑定到 exchange.fanout 交换机
     *
     * @param fanout       exchange.fanout 交换机
     * @param fanoutQueue2 fanoutQueue2
     * @return
     */
    @Bean
    public Binding fanoutBinding2(FanoutExchange fanout, Queue fanoutQueue2) {
        return BindingBuilder.bind(fanoutQueue2).to(fanout);
    }

    @Bean
    public FanoutReceiver fanoutReceiver() {
        return new FanoutReceiver();
    }

    @Bean
    public FanoutSender fanoutSender() {
        return new FanoutSender();
    }

}
